#include "card.h"

#include <algorithm>
#include <iostream>
#include <vector>

void Cards::check() {
  if (cards.size() == 0) {
    type = Cards::Type::unusable;
  } else if (cards.size() == 1) {
    type = Cards::Type::singal;
    first = cards[0];
  } else if (cards.size() == 2) {
    if (cards[0] == cards[1]) {
      type = Cards::Type::pair;
      first = cards[0];
    } else if (cards[0].point == 14 && cards[1].point == 15) {
      type = Cards::Type::king_bomb;
    } else
      type = Cards::Type::unusable;
  } else if (cards.size() == 3) {
    if (cards[0].point == cards[2].point) {
      type = Cards::Type::three;
      first = cards[0];
    } else
      type = Cards::Type::unusable;
  } else if (cards.size() == 4) {
    if (cards[0].point == cards[3].point) {
      type = Cards::Type::bomb;
      first = cards[0];
    } else if (cards[0].point == cards[2].point) {
      type = Cards::Type::three_one;
      first = cards[0];
      second = cards[3];
    } else if (cards[1].point == cards[3].point) {
      type = Cards::Type::three_one;
      first = cards[3];
      second = cards[0];
    } else
      type = Cards::Type::unusable;
  } else if (cards.size() == 5) {
    /*
    if(cards[0].point==cards[3].point){
            type=Cards::Type::four_one;
            first=cards[0].point;
            second=cards[4].point;
    }else if(cards[1].point==cards[4].point){
            type=Cards::Type::four_one;
            first=cards[4].point;
            second=cards[0].point;
    }else
    */
    if (cards[0].point == cards[2].point && cards[3].point == cards[4].point) {
      type = Cards::Type::three_two;
      first = cards[0];
      second = cards[4];
    } else if (cards[0].point == cards[1].point &&
               cards[2].point == cards[4].point) {
      type = Cards::Type::three_two;
      first = cards[4];
      second = cards[0];
    } else if (is_shun()) {
      type = Cards::Type::shun;
      first = cards[0];
      second = cards[4];
    } else
      type = Cards::Type::unusable;
  } else if (cards.size() == 6) {
    if (is_pairs()) {
      type = Cards::Type::shun_pair;
      first = cards[0];
      second = cards[5];
    } else if (cards[0] == cards[3]) {
      type = Cards::Type::four_two;
      first = cards[0]; // 这是因为每个点数四张牌，四带二必只用比四张的部分
      second = cards[4];
      third = cards[5];
    } else if (cards[1] == cards[4]) {
      type = Cards::Type::four_two;
      first = cards[1];
      second = cards[0];
      third = cards[5];
    } else if (cards[2] == cards[5]) {
      type = Cards::Type::four_two;
      first = cards[2];
      second = cards[0];
      third = cards[1];
    } else if (is_shun()) {
      type = Cards::Type::shun;
      first = cards[0];
      second = cards[5];
    } else if (cards[0] == cards[2] && cards[3] == cards[5] &&
               cards[2] == cards[3] + 1) {
      type = Cards::Type::plane;
      for_plane = new Plane;
      for_plane->main_begin = cards[0];
      for_plane->main_end = cards[5];
      for_plane->num = 2;
      for_plane->sub = 0;
    } else
      type = Cards::Type::unusable;
  } else if (is_shun()) {
    type = Cards::Type::shun;
    first = cards[0];
    second = cards[cards.size() - 1];
  } else if (is_pairs()) {
    type = Cards::Type::shun_pair;
    first = cards[0];
    second = cards[cards.size() - 1];
  } else if (!check_plane())
    type = Cards::Type::unusable;
}

bool Cards::is_shun() {
  for (auto i : cards)
    if (i.point == 2)
      return false;

  for (int i = 1; i < cards.size(); ++i)
    if (cards[i] != cards[i - 1] + 1)
      return false;
  return true;
}

bool Cards::is_pairs() {
  if (cards.size() % 2)
    return false;

  for (auto i : cards)
    if (i.point == 2)
      return false;

  for (int i = 0; i < cards.size(); i += 2)
    if (cards[i] != cards[i + 1])
      return false;

  for (int i = 2; i < cards.size(); i += 2)
    if (cards[i] != cards[i - 2] + 1)
      return false;

  return true;
}

bool Cards::check_plane() {
  std::vector<Card> main;
  std::vector<Card> sub;
  int sub_num = 0;

  for (int i = 0; i < cards.size();) {
    if (i + 2 < cards.size()) {
      if (cards[i] == cards[2 + i]) {
        main.push_back(cards[i]);
        i += 3;
        continue;
      }
    }
    if (i + 1 < cards.size()) {
      if (cards[i] == cards[i + 1]) {
        if (sub_num != 1) {
          sub_num = 2;
          sub.push_back(cards[i]);
          i += 2;
          continue;
        } else
          return false;
      }
    }
    if (i < cards.size()) {
      if (sub_num != 2) {
        sub_num = 1;
        sub.push_back(cards[i]);
        i++;
        continue;
      } else
        return false;
    }
  }

  if (!main.size())
    return false;
  if (main.size() != sub.size() && sub_num)
    return false;
  for (int i = 1; i < main.size(); i++)
    if (main[i] != main[i - 1] + 1)
      return false;

  for_plane = new Plane;
  for_plane->main_begin = main[0];
  for_plane->main_end = main[main.size() - 1];
  for_plane->num = main.size() / 3;
  for_plane->sub = sub_num;
  for_plane->a = std::move(sub);

  return true;
}

// 小于x返回1，大于返回0，不可比返回-1。支持直接比较，会判断是否可用
int Cards::compare_smaller(const Cards &x) const {
  if (type == Cards::Type::unusable || x.type == Cards::Type::unusable)
    return -1;

  if (type == Cards::Type::king_bomb)
    return 0;
  if (x.type == Cards::Type::king_bomb)
    return 1;

  if (type == Cards::Type::bomb) {
    if (x.type != Cards::Type::bomb)
      return 0;
    else
      return (first < x.first);
  } else if (x.type == Cards::Type::bomb)
    return 1;

  // 上面排除了王炸和炸弹的选项，下面就必须类型相同了
  if (type != x.type)
    return -1;

  // 飞机比较特殊，调用之前写好的飞机比较函数
  if (type == Cards::Type::plane) {
    if (!for_plane->can_compare(*(x.for_plane)))
      return -1;
    return (*for_plane < *(x.for_plane));
  }

  if (first == x.first) {
    if (second == x.second) {
      return (third < x.third);
    } else
      return (second < x.second);
  } else
    return (first < x.first);
}
